package com.woniuxy.annotion;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author: ideaAdmin
 * TODO:aspectj基于注解来配置Aop
 * Date: 2022/1/20:17:05
 * Description:
 */
@Aspect //aop需要使用 表明这个类是一个 切面
@Component //表示当前是一个组件 是一个util
public class annotationAspectj {

    //配置切面 需要一个空方法
    //(* com.woniuxy.service.*.*(..))
    //返回任意类型 com.woniuxy.service.*下的任意类 任意方法
    @Pointcut("execution(* com.woniuxy.service.*.*(..))")
    public void pointCut() {
    }



    //前置通知
    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("前置通知");
        System.out.println("当前被织入的增强目标是:" + joinPoint.getTarget().getClass().getName());
        System.out.println("被增强的方法是:" + joinPoint.getSignature().getName());
    }

    //后置通知
    @AfterReturning("pointCut()")
    public void afterReturning(JoinPoint joinPoint) {
        System.out.println("后置通知:模拟事务提交,结束时间：" + System.currentTimeMillis());
    }

    //环绕通知
    @Around("pointCut()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("开始环绕通知");
        //获得方法的参数
        Object[] args = proceedingJoinPoint.getArgs();

        Object proceed = proceedingJoinPoint.proceed();

        System.out.println("环绕结束 结束时间：" + System.currentTimeMillis());
    }

    //异常通知
    @AfterThrowing(value = "pointCut()",throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println("异常通知");
        System.out.println("报错信息" + e.getMessage());
    }

    //最终通知
    @After("pointCut()")
    @Order(Ordered.LOWEST_PRECEDENCE)
    public void after(JoinPoint joinPoint) throws InterruptedException {
        System.out.println("最终通知 模拟方法结束后释放资源 开始时间：" + System.currentTimeMillis());
        for (int i = 0; i < 100; i++) {
            Thread.sleep(10);
        }
        System.out.println("最终通知 模拟方法结束后释放资源 结束时间：" + System.currentTimeMillis());
    }
}
